﻿/******************************************************************************
 * Name         : cpm.js
 * Author       : 671643387
 * Date         : 2017年3月29日
 * Description  :
 *****************************************************************************/

var path        = require('path');
var fs          = require('fs');
var clone       = require('clone');
var async       = require('async');
var request     = require('request');
var exec        = require('child_process').exec;

//#############################################################################
// 命令表
var COMMAND_MAP = {
    '--create' : processCreateProject,
    '--install' : processInstall,
};

//#############################################################################
// 框架路径
var FRAMEWORK_URL = "http://rwf.codesb.com/";

//#############################################################################
// 程序入口
function main() {
    var argv = clone(process.argv);
    var cmdName = argv[2];
    var cmdArgs = argv.slice(3);
    processCommand(cmdName, cmdArgs, function(ok){
        process.exit(ok ? 0 : -1);
    });
}
main();

//#############################################################################
// 命令处理程序
function processCommand(cmdName, cmdArgs, callback) {
    var cmdProcessor = COMMAND_MAP[cmdName];
    cmdProcessor && cmdProcessor(cmdArgs, callback);
}

//#############################################################################
// 创建工程命令处理程序
function processCreateProject(cmdArgs, callback) {
    var cwd = process.cwd();
    var projName = cmdArgs[0];
    var projPath = path.join(cwd, projName);

    async.series([
        // 创建工程目录
        function (cb) {
            fs.mkdir(projPath, function(err){
                cb(err);
            });
        },
        // 创建配置文件
        function (cb) {
            var confStr = fs.readFileSync(__dirname + "/Project.json.template", "utf8");
            confStr = confStr.replace("$ProjectName$", projName);
            fs.writeFileSync(projPath + "/Project.json", confStr, "utf8");
            cb();
        }
    ], function(err){
        err && console.error(err);
        callback(!err);
    });
}

//#############################################################################
// 安装命令处理
function processInstall(cmdArgs, callback) {
    if (cmdArgs.length == 0) {
        // 安装配置文件中的模块
        var confStr = fs.readFileSync("Project.json", "utf8");
        var confObj = JSON.parse(confStr);

        // 安装框架
        var frameworks = confObj.Frameworks || [];
        frameworks.forEach(function(frameworkName){
            installFramework(frameworkName);
        });
    }
}

//#############################################################################
// 安装框架
function installFramework(frameworkName) {
    var fullURL = FRAMEWORK_URL + frameworkName + ".zip";
    var frameworkDir = getProjectPath() + "/Framework/";

    if (!fs.existsSync(frameworkDir)) {
        fs.mkdirSync(frameworkDir);
    }

    var fileName = frameworkDir + "/" + frameworkName + ".zip";

    // 下载文件
    downloadFile(fullURL, fileName, function(){
        // 解压文件
        unzip(frameworkDir, frameworkName + ".zip", function(){
            // 删除文件
            fs.unlinkSync(fileName);
        });
    });
}

//#############################################################################
// 下载文件
function downloadFile(url, fileName, callback) {
    var stream = fs.createWriteStream(fileName);
    request(url).pipe(stream).on("close", callback);
}

//#############################################################################
// 解压ZIP
function unzip(dir, fileName, callback) {
    var cmdStr = "cd " + dir;
    cmdStr += " && unzip " + fileName;
    execExternalCommand(cmdStr, callback);
}

//#############################################################################
// 获取工程路径
function getProjectPath(projName) {
    var cwd = process.cwd();
    return projName ? path.join(cwd, projName) : cwd;
}

//#############################################################################
// 执行命令
function execExternalCommand(cmdStr, callback) {
    exec(cmdStr, callback);
}